/*
 * Copyright 2020-2025 the original author or authors.
 * You cannot use this file unless authorized by the author.
 */

package org.ipig.data.mongo.impl;

import org.ipig.commons.conf.mongo.MongoConf;
import org.ipig.data.mongo.MongoService;
import com.mongodb.*;
import com.mongodb.client.MongoDatabase;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * MongoClientPool
 *
 * @author <a href="mailto:comchnts@163.com">chinats</a>
 * @version $$Id: MongoClientPool.java 3 2020-01-21 09:36:33Z ts <comchnts@163.com> $$
 * @since 1.0
 * @deprecated Replaced by {@link MongoManager}.
 */
@Deprecated
@Slf4j
public class MongoClientPool implements MongoService<MongoDatabase, MongoConf>, Serializable {
    /**
     * MongoClient
     */
    private MongoClient mongoClient;
    /**
     * MongoDatabase
     */
    private volatile MongoDatabase db;
    /**
     * mongodb连接配置
     */
    private MongoConf conf;

    /**
     * init
     */
    public void init() {
        if (null == db) {
            synchronized (this) {
                if (null == db) {
                    List<ServerAddress> list = new ArrayList<ServerAddress>();
                    List<MongoCredential> credentialsList = new ArrayList<MongoCredential>();
                    String[] addresss = conf.getAddress().split(",");
                    for (int i = 0; i < addresss.length; i++) {
                        String host = addresss[i].split(":")[0];
                        int port = Integer.parseInt(addresss[i].split(":")[1]);
                        ServerAddress serverAddress = new ServerAddress(host, port);
                        list.add(serverAddress);
                        if (StringUtils.isNotBlank(conf.getUserName()) && StringUtils.isNotBlank(conf.getPassword())) {
                            MongoCredential credentials = MongoCredential.createCredential(
                                    conf.getUserName(), conf.getDbName(), conf.getPassword().toCharArray());
                            credentialsList.add(credentials);
                        }
                    }
                    MongoClientOptions.Builder build = new MongoClientOptions.Builder();
                    build.writeConcern(new WriteConcern(conf.getOptionsWriteConcern()));
                    build.connectionsPerHost(conf.getCapacity());
                    build.threadsAllowedToBlockForConnectionMultiplier(
                            conf.getThreadsAllowedToBlockForConnectionMultiplier());
                    build.maxWaitTime(conf.getMaxWaitTime());
                    build.connectTimeout(conf.getConnectTimeout());
                    build.readPreference(parse(conf.getOptionsReadPreference()));
                    MongoClientOptions myOptions = build.build();
                    if (credentialsList != null && !credentialsList.isEmpty()) {
                        mongoClient = new MongoClient(list, credentialsList, myOptions);
                    } else {
                        mongoClient = new MongoClient(list, myOptions);
                    }
                    db = mongoClient.getDatabase(conf.getDbName());
                    log.debug("MongodbClientPool初始化完成");
                }
            }
        }
    }


    /**
     * 解析
     *
     * @param name 名称
     * @return ReadPreference
     */
    public static ReadPreference parse(final String name) {
        ReadPreference rp = null;
        if (StringUtils.isNotBlank(name)) {
            if (StringUtils.equalsIgnoreCase(name, ReadPreference.primary().getName())) {
                rp = ReadPreference.primary();
            } else if (StringUtils.equalsIgnoreCase(name, ReadPreference.secondary().getName())) {
                rp = ReadPreference.secondary();
            } else if (StringUtils.equalsIgnoreCase(name, ReadPreference.secondaryPreferred().getName())) {
                rp = ReadPreference.secondaryPreferred();
            } else if (StringUtils.equalsIgnoreCase(name, ReadPreference.primaryPreferred().getName())) {
                rp = ReadPreference.primaryPreferred();
            } else if (StringUtils.equalsIgnoreCase(name, ReadPreference.nearest().getName())) {
                rp = ReadPreference.nearest();
            }
        }
        if (rp == null) {
            rp = ReadPreference.primary();
        }
        return rp;
    }


    @Override
    public MongoDatabase getDatabase() {
        return db;
    }

    @Override
    public MongoDatabase getDatabase(String databaseName) {
        return mongoClient.getDatabase(databaseName);
    }

    @Override
    public MongoConf getConf() {
        return conf;
    }

    @Override
    public void setConf(MongoConf conf) {
        this.conf = conf;
    }
}
